module CcdCapture(
  //CCD side
  iVsync,      //Vertical sync output from CCD, indicates new frame   
  iHref,       //Horizontal window reference output, HIGH during a line (active window)
  iPclk,       //Pixel clock. Data is stable at rising edge.
  iFodd,       //Odd line signal, effective in interlaced mode only
  iDataYG,     //Digital data output (Y or G channel)
  //Output signals
  oRst,        //CCD chip reset
  oPwDn,       //Power down mode
  //RAM side
  oWrData,
  oWrAddress,
  oWrClk,
  //Image Processor Side
  oXCount,
  oYCount,
  iCaptureEn,
  oBusy
);

input iVsync, iHref, iPclk, iFodd;   
input [7:0] iDataYG;
input iCaptureEn;
output oBusy;
output oRst;
output oPwDn;
//RAM side
output [7:0]  oWrData;
output [18:0] oWrAddress;
output oWrClk;
//Misc register for counting pixels and frames
output reg [9:0] oXCount;
output reg [9:0] oYCount;

// --------------------- Parameters --------------------------------
parameter WIDTH = 640;
parameter HEIGHT = 480;
parameter FIRST_FRAME_VALID = 0;

// --------------------- internal registers and wires --------------
reg lStart = 0;                         // <= HREF 
reg frameEnabled = FIRST_FRAME_VALID;   // <= iCaptureEn
reg idle = 0;
reg prevVSync = 0;

// ------------------- assign blocks -------------------------------
assign oRst  = 1'b0;
assign oPwDn = 1'b0;
assign oWrData = (frameEnabled & lStart) ? iDataYG : 8'd0;
assign oWrAddress = (oYCount * WIDTH + oXCount);
assign oWrClk = (frameEnabled & lStart & ~idle) ? iPclk : 1'b0;
assign oBusy = frameEnabled & ~idle;

// ------------------- always blocks -------------------------------
always@(posedge iPclk) begin
  prevVSync <= iVsync;

  //Check frame start
  if({prevVSync,iVsync}==2'b01) begin
    oXCount <= 10'd0;
    oYCount <= 10'd0;
    idle <= 1'b0;
  end
  else begin
    //Pixel counting
    if(lStart) begin
      if(oXCount < (WIDTH-1)) begin
        oXCount <= oXCount + 1'b1;     
      end
      else begin
        oXCount <= 10'd0;
        oYCount <= oYCount + 1'b1;
      end
    end
   
    if(oWrAddress == (HEIGHT*WIDTH-1)) begin
      frameEnabled <= iCaptureEn;
      idle <= 1'b1;
    end
  end
end

//finding HREF
always@(negedge iPclk) begin
  //Check active line
  lStart <= iHref;
end

endmodule
